/**
 * 路由错误处理模块
 * 提供调试、错误日志及异常处理功能
 */

// 启用调试模式 (开发阶段设为true，生产环境设为false)
const ENABLE_DEBUG = true;

// 错误类型常量
const ERROR_TYPES = {
    NETWORK: 'network',
    PERMISSION: 'permission',
    VALIDATION: 'validation',
    BUSINESS: 'business',
    SYSTEM: 'system',
    UNKNOWN: 'unknown'
};

// 严重错误码范围
const CRITICAL_ERROR_CODES = [500, 1600, 2101, 2102, 2103, 2401, 2501];

/**
 * 调试日志
 * @param {String} message 日志消息
 * @param {Object} data 附加数据（可选）
 */
function debug(message, data) {
    if (!ENABLE_DEBUG) return;
    
    if (data !== undefined) {
        console.log(`[Router Debug] ${message}`, data);
    } else {
        console.log(`[Router Debug] ${message}`);
    }
}

/**
 * 错误日志
 * @param {Error|String} error 错误对象或消息
 * @param {Object} context 错误上下文（可选）
 */
function logError(error, context) {
    const errorMsg = error instanceof Error ? error.message : error;
    const stack = error instanceof Error ? error.stack : '';
    const code = error.code || 'UNKNOWN';
    
    if (context) {
        console.error(`[Router Error] ${errorMsg} (Code: ${code})`, context);
    } else {
        console.error(`[Router Error] ${errorMsg} (Code: ${code})`);
    }
    
    if (stack) {
        console.error(`[Router Error Stack] ${stack}`);
    }
    
    // 错误上报处理
    if (wx.getRealtimeLogManager) {
        const logger = wx.getRealtimeLogManager();
        logger.error({
            message: errorMsg,
            code: code,
            stack: stack,
            context: context || {},
            time: new Date().toISOString()
        });
    }
}

/**
 * 判断是否为网络错误
 * @param {*} error 错误对象
 * @returns {Boolean}
 */
function isNetworkError(error) {
    if (!error) return false;
    
    // 检查错误码
    if (error.code === 2601 || error.code === 2602) return true;
    
    // 检查错误消息中的关键词
    const message = String(error.message || error).toLowerCase();
    return message.includes('network') || 
           message.includes('断网') || 
           message.includes('timeout') || 
           message.includes('超时');
}

/**
 * 判断是否为严重错误
 * @param {*} code 错误码
 * @returns {Boolean}
 */
function isCriticalError(code) {
    return CRITICAL_ERROR_CODES.includes(Number(code));
}

/**
 * 格式化错误对象
 * @param {*} error 错误对象
 * @returns {Object} 格式化后的错误对象
 */
function formatError(error) {
    if (!error) {
        return { type: ERROR_TYPES.UNKNOWN, code: 0, message: '未知错误' };
    }
    
    // 提取错误信息
    const message = error.message || String(error);
    const code = error.code || 0;
    
    // 判断错误类型
    let type = ERROR_TYPES.UNKNOWN;
    if (isNetworkError(error)) {
        type = ERROR_TYPES.NETWORK;
    } else if (code === 1403 || code === 1405 || code === 2102) {
        type = ERROR_TYPES.PERMISSION;
    } else if (code === 1301 || code === 1401) {
        type = ERROR_TYPES.VALIDATION;
    } else if (code >= 2000 && code < 3000) {
        type = ERROR_TYPES.BUSINESS;
    } else if (code === 500) {
        type = ERROR_TYPES.SYSTEM;
    }
    
    return { type, code, message };
}

/**
 * 显示错误消息给用户
 * @param {String} message 错误消息
 * @param {Function} callback 回调函数（可选）
 */
function showError(message, callback) {
    wx.showToast({
        title: message,
        icon: 'none',
        duration: 2000,
        complete: () => {
            if (typeof callback === 'function') {
                setTimeout(callback, 2000);
            }
        }
    });
}

/**
 * 增强版错误提示
 * @param {*} error 错误对象
 * @param {Object} options 选项
 */
function showEnhancedError(error, options = {}) {
    // 格式化错误信息
    const { type, code, message } = formatError(error);
    const { showDetail = false, duration = 2000, callback } = options;
    
    // 根据错误类型选择不同提示方式
    if (type === ERROR_TYPES.NETWORK) {
        wx.showModal({
            title: '网络连接错误',
            content: '请检查网络连接后重试',
            showCancel: false,
            success: () => callback && callback()
        });
        return;
    }
    
    // 严重错误使用Modal
    if (isCriticalError(code)) {
        wx.showModal({
            title: '操作失败',
            content: message + (showDetail ? `\n错误码：${code}` : ''),
            showCancel: false,
            success: () => callback && callback()
        });
        return;
    }
    
    // 验证错误使用详细提示
    if (type === ERROR_TYPES.VALIDATION) {
        wx.showModal({
            title: '输入有误',
            content: message,
            showCancel: false,
            success: () => callback && callback()
        });
        return;
    }
    
    // 一般错误使用Toast
    wx.showToast({
        title: message,
        icon: 'error',
        duration,
        complete: () => {
            if (typeof callback === 'function') {
                setTimeout(callback, duration);
            }
        }
    });
    
    // 记录到日志
    logError(error, options.context || {});
}

/**
 * 执行函数，并捕获异常
 * @param {Function} fn 要执行的函数
 * @param {Function} errorHandler 错误处理函数（可选）
 * @param {Object} context 执行上下文（可选）
 * @returns {*} 函数执行结果
 */
function tryCatch(fn, errorHandler, context) {
    try {
        if (context) {
            return fn.call(context);
        }
        return fn();
    } catch (error) {
        logError(error, { context: '路由异常捕获', function: fn.name });
        
        if (typeof errorHandler === 'function') {
            return errorHandler(error);
        }
        
        // 默认错误处理
        showEnhancedError(error);
        return null;
    }
}

// 导出函数
module.exports = {
    debug,
    logError,
    showError,
    showEnhancedError,
    tryCatch,
    formatError,
    ERROR_TYPES,
    isNetworkError,
    isCriticalError
}; 